package com.tongzhan.service.impl;

import com.tongzhan.base.PageInfo;
import com.tongzhan.base.Return;
import com.tongzhan.data.vo.PicVO;
import com.tongzhan.data.vo.SiteInfoDetailsVO;
import com.tongzhan.data.vo.SiteInfoVO;
import com.tongzhan.entity.User;
import com.tongzhan.entity.religion.*;
import com.tongzhan.repository.UserRepository;
import com.tongzhan.repository.religion.*;
import com.tongzhan.service.SiteService;
import com.tongzhan.utils.SnowFlakeUtils;
import com.tongzhan.utils.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class SiteServiceImpl implements SiteService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private StreetRepository streetRepository;

    @Autowired
    private VillageRepository villageRepository;

    @Autowired
    private ReligionRepository religionRepository;

    @Autowired
    private SiteRepository siteRepository;

    @Autowired
    private SiteInfoRepository siteInfoRepository;

    @Override
    public Site selectByCode(String siteCode) {
        return siteRepository.findByPrimaryKey(siteCode);
    }

    @Override
    public Return addSite(Site site, String address, String beliefType, String buildYears, String historyEvolution, String believers, String picture, String personName, String personTelephone, String creditCode, String registrationNo) {
        //校验场所名是否重复
        Query query = new Query();
        query.addCriteria(Criteria.where("StreetCode").is(site.getStreetCode())
                .and("VillageCode").is(site.getVillageCode())
                .and("SiteName").is(site.getSiteName()));
        Site siteRepositoryOne = siteRepository.findOne(query);
        if (siteRepositoryOne != null) {
            return new Return(Return.FAIL, "该场所名已被添加");
        }
        //场所详细信息
        SiteInfo siteInfo = new SiteInfo();
        //生成场所编码
        SnowFlakeUtils snow = new SnowFlakeUtils(4, 7);
        String siteCode = String.valueOf(snow.nextId());
        site.setSiteCode(siteCode);
        siteInfo.setSiteCode(siteCode);
        siteInfo.setSiteName(site.getSiteName());
        siteInfo.setSiteInfoCode(String.valueOf(snow.nextId()));
        siteInfo.setCreditCode(creditCode);
        if (StringUtils.isNotEmpty(registrationNo)) {
            siteInfo.setRegistrationNo(registrationNo.trim());
        }
        //街道
        Street street = streetRepository.findByPrimaryKey(site.getStreetCode());
        if (street != null) {
            site.setStreetName(street.getStreetName());
            siteInfo.setStreetCode(street.getStreetCode());
            siteInfo.setStreetName(street.getStreetName());
        }
        //宗教团体
        Religion religion = religionRepository.findByPrimaryKey(site.getReligionCode());
        if (religion != null) {
            site.setReligionName(religion.getReligionName());
            siteInfo.setReligionCode(religion.getReligionCode());
            siteInfo.setReligionName(religion.getReligionName());
        }
        //村社区
        Village village = villageRepository.findByPrimaryKey(site.getVillageCode());
        if (village != null) {
            site.setVillageName(village.getVillageName());
            siteInfo.setVillageCode(village.getVillageCode());
            siteInfo.setVillageName(village.getVillageName());
        }
        siteInfo.setAddress(address);
        siteInfo.setBeliefType(beliefType);
        siteInfo.setBuildYears(buildYears);
        siteInfo.setHistoryEvolution(historyEvolution);
        siteInfo.setBelievers(believers);
        if ("04".equals(site.getReligionCode())) {
            siteInfo.setType(1);
        } else {
            siteInfo.setType(0);
        }
        siteInfo.setPicture(picture);
        if (StringUtils.isNotEmpty(personName)) {
            siteInfo.setPersonName(personName.trim());
        }
        //查询对应教派Sort最大数据
        SiteInfo maxSort = siteInfoRepository.findOne(new Query().with(Sort.by(Sort.Direction.DESC, "Sort"))
                .addCriteria(Criteria.where("ReligionCode").is(site.getReligionCode())));
        siteInfo.setSort(maxSort.getSort() + 1);
        //是否受管辖，默认是
        siteInfo.setJurisdiction("是");
        siteInfo.setPersonTelephone(personTelephone);
        siteInfo.setCreateTime(LocalDateTime.now());
        site.setCreateTime(LocalDateTime.now());
        siteRepository.insert(site);
        siteInfoRepository.insert(siteInfo);
        return new Return(Return.SUCCESS);
    }

    @Override
    public Return getSiteList(String religionCode, Integer page, Integer size) {
        //查询条件
        Query query = new Query();
        if (StringUtils.isNotEmpty(religionCode)) {
            query.addCriteria(Criteria.where("ReligionCode").is(religionCode));
        } else {
            query.with(Sort.by(Sort.Direction.ASC, "ReligionCode"));
        }
        query.with(Sort.by(Sort.Direction.ASC, "Sort"));
        //获取当前登录用户信息
        ThreadLocalUtil.AdminThreadLocal threadLocal = ThreadLocalUtil.getThreadLocal();
        //权限编码
        String dutiesCode = threadLocal.getDutiesCode();
        if (ThreadLocalUtil.STREET_CODE.equals(dutiesCode)) {
            //镇街道
            query.addCriteria(Criteria.where("StreetCode").is(threadLocal.getStreetCode()));
        } else if (ThreadLocalUtil.VILLAGE_CODE.equals(dutiesCode)) {
            //村社区
            query.addCriteria(Criteria.where("VillageCode").is(threadLocal.getVillageCode()));
        }
        Page<SiteInfo> pages = siteInfoRepository.findPage(query, PageRequest.of(page - 1, size));
        //场所列表
        List<SiteInfo> siteInfos = pages.getContent();
        //VO
        List<SiteInfoVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(siteInfos)) {
            for (SiteInfo siteInfo : siteInfos) {
                SiteInfoVO vo = new SiteInfoVO();
                //去除场所名称中已拆
                String siteName = siteInfo.getSiteName();
                if (siteName.contains("（已拆）")) {
                    vo.setSiteName(siteName.substring(0, siteName.indexOf("（")));
                } else if (siteName.contains("(已拆)")){
                    vo.setSiteName(siteName.substring(0, siteName.indexOf("(")));
                } else {
                    vo.setSiteName(siteName);
                }
                vo.setSiteInfoCode(siteInfo.getSiteInfoCode());
                vo.setAddress(siteInfo.getAddress());
                vo.setJurisdiction(siteInfo.getJurisdiction());
                List<PicVO> picList = new ArrayList<>();
                //图片
                String picture = siteInfo.getPicture();
                if (StringUtils.isNotEmpty(picture)) {
                    String[] files = picture.split(",");
                    for (String file : files) {
                        PicVO picVO = new PicVO();
                        picVO.setPath(file);
                        picList.add(picVO);
                    }
                }
                vo.setPicList(picList);
                vos.add(vo);
            }
        }
        //分页
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPage(page);
        pageInfo.setSize(vos.size());
        pageInfo.setTotal(pages.getTotalElements());
        //封装返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("siteList", vos);
        map.put("pageInfo", pageInfo);
        return new Return(map);
    }

    @Override
    public Return siteDetails(String siteInfoCode) {
        //VO
        SiteInfoDetailsVO vo = new SiteInfoDetailsVO();
        //场所信息
        SiteInfo siteInfo = siteInfoRepository.findByPrimaryKey(siteInfoCode);
        if (siteInfo != null) {
            vo.setSiteCode(siteInfo.getSiteCode());
            vo.setSiteInfoCode(siteInfo.getSiteInfoCode());
            //去除场所名称中已拆
            String siteName = siteInfo.getSiteName();
            if (siteName.contains("（已拆）")) {
                vo.setSiteName(siteName.substring(0, siteName.indexOf("（")));
            } else if (siteName.contains("(已拆)")){
                vo.setSiteName(siteName.substring(0, siteName.indexOf("(")));
            } else {
                vo.setSiteName(siteName);
            }
            vo.setStreetCode(siteInfo.getStreetCode());
            vo.setVillageCode(siteInfo.getVillageCode());
            vo.setReligionCode(siteInfo.getReligionCode());
            vo.setReligionName(siteInfo.getReligionName());
            vo.setAddress(siteInfo.getAddress());
            vo.setBeliefType(siteInfo.getBeliefType());
            vo.setBelievers(siteInfo.getBelievers());
            vo.setBuildYears(siteInfo.getBuildYears());
            vo.setPersonName(siteInfo.getPersonName());
            vo.setPersonTelephone(siteInfo.getPersonTelephone());
            vo.setCreditCode(siteInfo.getCreditCode());
            vo.setRegistrationNo(siteInfo.getRegistrationNo());
            vo.setJurisdiction(siteInfo.getJurisdiction());
            vo.setType(siteInfo.getType());
            vo.setHistoryEvolution(siteInfo.getHistoryEvolution());
            //图片
            String picture = siteInfo.getPicture();
            List<PicVO> picList = new ArrayList<>();
            if (StringUtils.isNotEmpty(picture)) {
                String[] files = picture.split(",");
                for (String file : files) {
                    PicVO picVO = new PicVO();
                    picVO.setPath(file);
                    picList.add(picVO);
                }
            }
            vo.setPicList(picList);
        }
        return new Return(vo);
    }

    @Override
    public List<SiteInfo> selectNotReported(List<String> isReportedList) {
        //查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("Jurisdiction").is("是"))
                .addCriteria(Criteria.where("SiteCode").nin(isReportedList));
        List<SiteInfo> siteInfos = siteInfoRepository.findAll(query);
        if (CollectionUtils.isEmpty(siteInfos)) {
            return new ArrayList<>();
        }
        return siteInfos;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Return changeSort(String siteInfoCode, Integer type) {
        try {
            //场所详细信息
            SiteInfo siteInfo = siteInfoRepository.findByPrimaryKey(siteInfoCode);
            if (siteInfo == null) {
                return new Return(Return.FAIL, "场所不存在");
            }
            //需要交换的场所
            SiteInfo needSwap;
            //查询条件
            Query query = new Query();
            query.addCriteria(Criteria.where("ReligionCode").is(siteInfo.getReligionCode()));
            if (type == 1) {
                //上升
                query.with(Sort.by(Sort.Direction.DESC, "Sort"));
                query.addCriteria(Criteria.where("Sort").lt(siteInfo.getSort()));
                //查询Sort靠前一位的场所信息
                needSwap = siteInfoRepository.findOne(query);
                if (needSwap == null) {
                    return new Return(Return.FAIL, "已经到顶了");
                }
                Integer sort = needSwap.getSort();
                needSwap.setSort(siteInfo.getSort());
                siteInfo.setSort(sort);
                siteInfoRepository.updateByPrimaryKey(needSwap);
            } else if (type == 2) {
                //下降
                query.with(Sort.by(Sort.Direction.ASC, "Sort"));
                query.addCriteria(Criteria.where("Sort").gt(siteInfo.getSort()));
                //查询Sort靠后一位的场所信息
                needSwap = siteInfoRepository.findOne(query);
                if (needSwap == null) {
                    return new Return(Return.FAIL, "已经到底了");
                }
                Integer sort = needSwap.getSort();
                needSwap.setSort(siteInfo.getSort());
                siteInfo.setSort(sort);
                siteInfoRepository.updateByPrimaryKey(needSwap);
            } else {
                //置顶
                query.with(Sort.by(Sort.Direction.ASC, "Sort"));
                query.addCriteria(Criteria.where("Sort").lt(siteInfo.getSort()));
                //查询Sort第一位的场所信息
                List<SiteInfo> sortList = siteInfoRepository.findAll(query);
                if (sortList.size() == 0) {
                    return new Return(Return.FAIL, "已经到顶了");
                }
                needSwap = sortList.get(0);
                siteInfo.setSort(needSwap.getSort());
                //后续列表依次Sort后移
                for (SiteInfo info : sortList) {
                    info.setSort(info.getSort() + 1);
                    siteInfoRepository.updateByPrimaryKey(info);
                }
            }
            siteInfoRepository.updateByPrimaryKey(siteInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Return(Return.SUCCESS, "操作成功");
    }

    @Override
    public SiteInfo selectSiteInfoByCode(String siteInfoCode) {
        return siteInfoRepository.findByPrimaryKey(siteInfoCode);
    }

    @Override
    public Return editSiteInfo(SiteInfo siteInfo) {
        //用户信息
        User user = userRepository.findOne(new Query().addCriteria(Criteria.where("SiteCode").is(siteInfo.getSiteCode())));
        //宗教
        Religion religion = religionRepository.findByPrimaryKey(siteInfo.getReligionCode());
        siteInfo.setReligionName(religion.getReligionName());
        if (user != null) {
            user.setReligionCode(religion.getReligionCode());
            user.setReligionName(religion.getReligionName());
        }
        //街道
        Street street = streetRepository.findByPrimaryKey(siteInfo.getStreetCode());
        siteInfo.setStreetName(street.getStreetName());
        if (user != null) {
            user.setStreetCode(street.getStreetCode());
            user.setStreetName(street.getStreetName());
        }
        //村社区
        Village village = villageRepository.findByPrimaryKey(siteInfo.getVillageCode());
        siteInfo.setVillageName(village.getVillageName());
        if (user != null) {
            user.setVillageCode(village.getVillageCode());
            user.setVillageName(village.getVillageName());
        }
        //场所信息
        Site site = siteRepository.findByPrimaryKey(siteInfo.getSiteCode());
        if (site != null) {
            site.setReligionCode(religion.getReligionCode());
            site.setReligionName(religion.getReligionName());
            site.setSiteName(siteInfo.getSiteName());
            site.setStreetCode(street.getStreetCode());
            site.setStreetName(street.getStreetName());
            site.setVillageCode(village.getVillageCode());
            site.setVillageName(village.getVillageName());
            siteRepository.updateByPrimaryKey(site);
        }
        siteInfoRepository.updateByPrimaryKey(siteInfo);
        return new Return(Return.SUCCESS, "修改成功");
    }

    @Override
    public void delete(String siteInfoCode) {
        SiteInfo siteInfo = siteInfoRepository.findByPrimaryKey(siteInfoCode);
        if (siteInfo != null) {
            siteRepository.deletePrimaryKey(siteInfo.getSiteCode());
            siteInfoRepository.deletePrimaryKey(siteInfoCode);
        }
    }
}
